const fs = require("fs");
const path = require("path");
const readline = require("readline");
const _ = require("koa-route");
const Koa = require("koa");
const { koaBody } = require("koa-body");
const app = new Koa();
const { WebSocketServer } = require("ws");
const game = createGame();
const { plusPort } = require("./config");
const ip = require("koa-ip");
// app.use(ip(["::1", "172.31.18.95"])); // whitelist
app.use(koaBody());

app.use(
  _.post("/play", (ctx) => {
    ctx.body = game.update(ctx.request.body);
  })
);
app.use(
  _.post("/start", (ctx) => {
    console.log(ctx.host, ctx.ip);
    game.start(ctx.request.body);
  })
);
app.use(
  _.post("/end", (ctx) => {
    game.end();
  })
);

app.use((ctx) => {});

function createGame() {
  let gameId = "";
  readline.emitKeypressEvents(process.stdin);
  process.stdin.setRawMode(true);
  let moveType = "STOP";
  let shoot = false;
  const maps = [];
  let inited = false;
  const wss = new WebSocketServer({
    port: 9999,
  });
  let wsClient;
  wss.on("connection", (ws) => {
    wsClient = ws;
    ws.on("message", (msg) => {
      try {
        const { url, data } = JSON.parse(msg.toString("utf8"));
        if (url === "move") {
          moveType = data.moveType;
          if (data.shoot) {
            shoot = data.shoot;
          }
        } else if (url === "init") {
          inited = false;
        }
      } catch (error) {
        console.error(error);
      }
    });
  });
  process.stdin.on("keypress", (str, key) => {
    if (key.ctrl && key.name === "c") {
      end();
      process.exit(0);
    }
  });
  function sendMsg(data) {
    try {
      wsClient.send(JSON.stringify(data));
    } catch (error) {
      setTimeout(() => {
        sendMsg(data);
      }, 1000);
    }
  }
  function end() {
    const html = fs.readFileSync("./render/template.html", "utf-8");
    const fileName = `../dist/plus/game_${gameId}.html`;
    const dir = path.dirname(fileName);
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    fs.writeFileSync(
      fileName,
      html.replace("$mockData$", JSON.stringify(maps))
    );
    sendMsg({
      cmd: "end",
    });
  }
  return {
    update(data) {
      if (data.battleId) {
        if (data.battleId !== gameId) {
          moveType = "TOP";
          maps.length = 0;
        }
        gameId = data.battleId;
        if (!inited) {
          sendMsg({
            cmd: "start",
            data: data.map,
          });
          inited = true;
        }
        try {
          const dataCopy = JSON.parse(JSON.stringify(data));
          dataCopy.map = [];
          dataCopy.bulletSateVoList =
            dataCopy.bulletSateVoList?.map((item) => {
              return {
                x: item.x,
                y: item.y,
              };
            }) || [];
          dataCopy.propVoList =
            dataCopy.propVoList?.map((item) => {
              return {
                propTypeEnums: item.propTypeEnums,
                x: item.x,
                y: item.y,
              };
            }) || [];
          dataCopy.tankSatesVoList.map((item) => {
            item.tankId =
              item.tankId === dataCopy.tankId ? "host" : item.tankId;
            return item;
          });

          sendMsg({
            cmd: "action",
            data: dataCopy,
          });

          const response = {
            moveType,
            shoot: true,
          };

          return response;
        } catch (error) {}
      }
      return {
        moveType: "STOP",
        shoot: false,
      };
    },
    start(data) {},
    end,
  };
}
app.listen(plusPort);

console.log("服务已启动：", "http://localhost:" + plusPort);
